import { Service } from "@/middleware/response";
import { PermissionModel } from "@/models/admin/Permission";
import { Permission } from "@/types/admin/permission";
import { PageReq } from "@/types/common/common";
import {
    catchError,
    createRecord,
    deleteRecord,
    getPageList,
    GetPageListOptions,
    getRecord,
    updateRecord,
    GetChildrenPageListOptions,
    getChildrenPageList,
    GetRecordOptions,
    CreateRecordOptions,
    UpdateRecordOptions,
    DeleteRecordOptions,
} from "@/utils/db";
import { RoleModel } from "@/models/admin/Role";
import lodash from "lodash";
import { Types } from "mongoose";
import { setUserRolePermission } from "@/middleware/admin/auth";

export type TreePermissionItem = Omit<Permission, "children"> & { parentId?: string; children?: TreePermissionItem[] };
const fromPermissionToTreeData = (list: Permission[]) => {
    const fromIdToRecord = (id: Types.ObjectId) => list.find(item => item._id.toString() === id.toString());
    const getParentIdById = (id: string) => {
        return list.find(item => item.children?.some((child: Types.ObjectId) => child.toString() === id))?._id.toString();
    };
    const getChildren = (recordList: Permission[]): TreePermissionItem[] => {
        return recordList?.map(item => {
            const childObj = {
                ...item,
                parentId: getParentIdById(item._id.toString()),
                children: item.children
                    ?.map(child => {
                        const res = lodash.cloneDeep(list.find(listItem => listItem._id.toString() === child.toString()));
                        const childObj = {
                            ...res,
                            parentId: child.toString(),
                            children: getChildren(res?.children?.map((child: Types.ObjectId) => fromIdToRecord(child) as Permission) || []),
                        };
                        if (!childObj.children?.length) {
                            const { children, ...returnObj } = childObj;
                            return returnObj;
                        }
                        return childObj;
                    })
                    .filter(item => item._id),
            };
            if (!childObj.children?.length) {
                const { children, ...returnObj } = childObj;
                return returnObj;
            }
            return childObj;
        }) as TreePermissionItem[];
    };
    return getChildren(list).filter(item => !item.parentId);
};

export const getPermissionListService: Service = async (req, res) => {
    const { page, pageSize, ...match } = req.query;
    const { name, key, type } = match;
    const options: GetPageListOptions<Permission> = {
        model: PermissionModel,
        params: { page: 1, pageSize: 999999 },
        $sort: { sort: 1 },
    };
    if (name || key || type) options.$match = {};
    if (![undefined, null, ""].includes(type as undefined | null | string)) options.$match!.type = type;
    if (options.$match) {
        if (name && typeof name === "string") options.$match.name = { $regex: RegExp(name), $options: "i" };
        if (key && typeof key === "string") options.$match.key = { $regex: RegExp(key), $options: "i" };
    }
    catchError({
        async operation() {
            const { list } = await getPageList(options);
            const data = fromPermissionToTreeData(list);
            res.sendResponse!(200, data);
        },
        res,
        type: "查询",
    });
};

export const getUserPermissionListService: Service = async (req, res) => {
    catchError({
        async operation() {
            const { list } = await getPageList({ model: PermissionModel, params: { page: 1, pageSize: 999999 }, $sort: { sort: 1 } });
            const allTreePermission = fromPermissionToTreeData(list);
            await setUserRolePermission(req, res);
            const userPermissionList = req.session.permissions || [];
            // 将用户权限列表的 `_id` 提取出来，方便快速查找
            const userPermissionIds = new Set(userPermissionList.map(perm => perm._id.toString()));
            // 递归函数：遍历权限树，构建包含用户权限及其父节点的树
            const filterTree = (permissionTree: TreePermissionItem[]): TreePermissionItem[] => {
                const result: TreePermissionItem[] = [];
                for (const item of permissionTree) {
                    // 检查当前节点是否在用户权限中，或者其子节点中是否存在用户权限
                    const children = filterTree(item.children || []);
                    const isInUserPermissions = userPermissionIds.has(item._id.toString());
                    // 如果当前节点在用户权限中，或者有子节点被包含，则保留当前节点
                    if (isInUserPermissions || children.length) {
                        result.push({
                            ...item,
                            children, // 保留符合条件的子节点
                        });
                    }
                }
                return result;
            };
            // 从根节点开始过滤权限树
            return filterTree(allTreePermission);
        },
        res,
        type: "查询",
    });
};
export const getPermissionDetailService: Service = async (req, res) => {
    const { _id } = req.params;
    const childFields: GetRecordOptions<Permission>["childFields"] = [];
    catchError({
        async operation() {
            return await getRecord({ model: PermissionModel, _id, childFields });
        },
        res,
        type: "查询",
    });
};
export const createPermissionService: Service = async (req, res) => {
    const { ...data } = req.body;
    catchError({
        async operation() {
            const childFields: CreateRecordOptions<Permission>["childFields"] = [];
            return await createRecord({ model: PermissionModel, childFields, data });
        },
        res,
        type: "创建",
    });
};
export const updatePermissionService: Service = async (req, res) => {
    const { _id, ...data } = req.body;
    catchError({
        async operation() {
            const childFields: UpdateRecordOptions<Permission>["childFields"] = [];
            return await updateRecord({ model: PermissionModel, _id, childFields, data });
        },
        res,
        type: "更新",
    });
};
export const deletePermissionService: Service = async (req, res) => {
    const { _id } = req.body;
    const childFields: DeleteRecordOptions<Permission>["childFields"] = [];
    const parentFields: DeleteRecordOptions<Permission>["parentFields"] = [{ key: "children", model: PermissionModel }];
    catchError({
        async operation() {
            return await deleteRecord({ model: PermissionModel, _id, childFields, parentFields });
        },
        res,
        type: "删除",
    });
};
export const getItemsService: Service = async (req, res) => {
    const { _id, ...match } = req.query;
    const { name, key, type } = match;
    const options: GetChildrenPageListOptions<Permission> = {
        model: PermissionModel,
        params: req.query as PageReq,
        parentKey: "_id",
        parentValue: _id,
        parentModel: RoleModel,
        localField: "permissions",
        foreignField: "_id",
    };
    if (name || key || type) options.$match = {};
    if (![undefined, null, ""].includes(type as undefined | null | string)) options.$match!.type = type;
    if (options.$match) {
        if (typeof name === "string") options.$match.name = { $regex: RegExp(name), $options: "i" };
        if (typeof key === "string") options.$match.key = { $regex: RegExp(key), $options: "i" };
    }
    catchError({
        async operation() {
            const result = await getChildrenPageList(options);
            res.sendResponse!(200, result);
        },
        res,
        type: "查询",
    });
};
